import 'package:flutter/material.dart';

typedef MyFieldCallback = void Function(String str);

enum MyFieldBorder {
  none,
  underline, //底部一条线
  outline, //圆角边框
}

enum _borderType {
  normal,
  focused, //底部一条线
  disabled, //圆角边框
  enabled, //圆角边框
  error, //圆角边框
  // outline,//圆角边框
  // outline,//圆角边框
}

const String _eyesClosedImagPath = "assets/img/EyesClosed.png";
const String _eyesOpenImagPath = "assets/img/EyesOpen.png";

class MyField extends StatefulWidget {
  final TextEditingController? controller;
  final FocusNode? focusNode;
  final String? errorText;
  final String? hintText;
  final int maxLength;
  final bool showClearButton; //显示清空按钮
  final bool showPasswordButton; //显示查看密码按钮
  bool obscureText;
  final MyFieldBorder border;
  final double borderWidth; //边框宽度
  final Color borderColor; //边框颜色
  final Color? borderFocusedColor; //边框焦点颜色
  final Color borderErrorColor; //边框错误颜色
  final TextAlign textAlign;
  final TextInputType? keyboardType; //键盘类型
  final MyFieldCallback? onChanged; //
  final ValueChanged<String>? onSubmitted;

  MyField({
    this.controller,
    this.focusNode,
    this.errorText,
    this.hintText,
    this.maxLength = -1,
    this.showClearButton = true,
    this.showPasswordButton = false,
    this.border: MyFieldBorder.outline,
    this.borderWidth = 1.4,
    this.borderColor = Colors.grey,
    this.borderFocusedColor,
    this.borderErrorColor = Colors.redAccent,
    this.keyboardType,
    this.obscureText: false,
    this.onChanged,
    this.textAlign = TextAlign.start,
    this.onSubmitted,
  });

  @override
  _MyFieldState createState() => _MyFieldState();
}

class _MyFieldState extends State<MyField> {
  bool showPassword = false;
  bool showClearButton = false;
  VoidCallback? onControllerCallback;

  Widget? suffixIcon() {
    if (widget.showClearButton || widget.showPasswordButton) {
      return Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          Visibility(
            visible: widget.showClearButton && showClearButton,
            child: IconButton(
              onPressed: widget.controller?.clear,
              icon: const Icon(
                Icons.clear,
                color: Colors.grey,
              ),
            ),
          ),
          Visibility(
            visible: widget.obscureText && widget.showPasswordButton,
            child: IconButton(
              onPressed: () {
                setState(() {
                  showPassword = !showPassword;
                });
              },
              icon: Image.asset(
                showPassword ? _eyesOpenImagPath : _eyesClosedImagPath,
                height: 26,
                width: 26,
                color: Colors.grey,
              ),
            ),
          ),
        ],
      );
    }
    return null;
  }

  InputBorder outlineBorder(_borderType type) {
    switch (type) {
      case _borderType.error:
        return OutlineInputBorder(
            borderSide: BorderSide(
                width: widget.borderWidth, color: widget.borderErrorColor));
      case _borderType.focused:
        return OutlineInputBorder(
            borderSide: BorderSide(
                width: widget.borderWidth + 0.5,
                color: widget.borderFocusedColor ?? widget.borderColor));
      case _borderType.normal:
        // TODO: Handle this case.
        break;
      case _borderType.disabled:
        // TODO: Handle this case.
        break;
      case _borderType.enabled:
        // TODO: Handle this case.
        break;
    }
    return OutlineInputBorder(
        borderSide:
            BorderSide(width: widget.borderWidth, color: widget.borderColor));
  }

  InputBorder underlineBorder(_borderType type) {
    switch (type) {
      case _borderType.error:
        return UnderlineInputBorder(
            borderSide: BorderSide(
                width: widget.borderWidth, color: widget.borderErrorColor));
      case _borderType.focused:
        return UnderlineInputBorder(
            borderSide: BorderSide(
                width: widget.borderWidth + 0.5,
                color: widget.borderFocusedColor ?? widget.borderColor));
      case _borderType.normal:
        // TODO: Handle this case.
        break;
      case _borderType.disabled:
        // TODO: Handle this case.
        break;
      case _borderType.enabled:
        // TODO: Handle this case.
        break;
    }
    return UnderlineInputBorder(
        borderSide:
            BorderSide(width: widget.borderWidth, color: widget.borderColor));
  }

  @override
  void initState() {
    // TODO: implement initState
    onControllerCallback = () {
      if (widget.onChanged != null) {
        widget.onChanged!(widget.controller!.text);
      }
      setState(() {
        if (widget.controller!.text.isEmpty) {
          showClearButton = false;
        } else {
          showClearButton = true;
        }
      });
    };

    if (widget.controller != null) {
      if (widget.controller!.text.isEmpty) {
        showClearButton = false;
      } else {
        showClearButton = true;
      }
      widget.controller?.addListener(onControllerCallback!);
    }

    super.initState();
  }

  @override
  void dispose() {
    widget.controller?.removeListener(onControllerCallback!);
    // TODO: implement dispose
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: widget.controller,
      focusNode: widget.focusNode,
      maxLength: widget.maxLength,
      textAlign: widget.textAlign,
      keyboardType: widget.keyboardType,
      obscureText: widget.obscureText ? !showPassword : false,
      decoration: InputDecoration(
        errorText: widget.errorText == null || widget.errorText!.isEmpty
            ? null
            : widget.errorText,
        hintText: widget.hintText,

        counterText: '',
        //隐藏maxLength
        suffixIcon: suffixIcon(),
        focusedErrorBorder: widget.border == MyFieldBorder.none
            ? InputBorder.none
            : widget.border == MyFieldBorder.outline
                ? outlineBorder(_borderType.error)
                : underlineBorder(_borderType.error),
        errorBorder: widget.border == MyFieldBorder.none
            ? InputBorder.none
            : widget.border == MyFieldBorder.outline
                ? outlineBorder(_borderType.error)
                : underlineBorder(_borderType.error),
        focusedBorder: widget.border == MyFieldBorder.none
            ? InputBorder.none
            : widget.border == MyFieldBorder.outline
                ? outlineBorder(_borderType.focused)
                : underlineBorder(_borderType.focused),
        enabledBorder: widget.border == MyFieldBorder.none
            ? InputBorder.none
            : widget.border == MyFieldBorder.outline
                ? outlineBorder(_borderType.enabled)
                : underlineBorder(_borderType.enabled),
        border: widget.border == MyFieldBorder.none
            ? InputBorder.none
            : widget.border == MyFieldBorder.outline
                ? outlineBorder(_borderType.normal)
                : underlineBorder(_borderType.normal),
        disabledBorder: widget.border == MyFieldBorder.none
            ? InputBorder.none
            : widget.border == MyFieldBorder.outline
                ? outlineBorder(_borderType.disabled)
                : underlineBorder(_borderType.disabled),
      ),
      onSubmitted: widget.onSubmitted,
    );
  }
}
